package top.jiangqiang.qianyi.generator.freemarker;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.config.builder.CustomFile;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import org.apache.commons.collections4.keyvalue.DefaultMapEntry;
import org.dromara.hutool.core.io.file.FileNameUtil;
import org.dromara.hutool.core.reflect.FieldUtil;
import org.dromara.hutool.core.text.StrUtil;
import org.jetbrains.annotations.NotNull;
import top.jiangqiang.qianyi.generator.model.EnhanceCustomFile;

import java.io.File;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.stream.Collectors;

public final class EnhanceFreemarkerTemplateEngine extends FreemarkerTemplateEngine {
    @Override
    protected void outputCustomFile(@NotNull List<CustomFile> customFiles, @NotNull TableInfo tableInfo, @NotNull Map<String, Object> dataMap) {
        String parentPath = getPathInfo(OutputFile.parent);
        for (CustomFile file : customFiles) {
            String filePath = StringUtils.isNotBlank(file.getFilePath()) ? file.getFilePath() : parentPath;
            Function<TableInfo, String> formatNameFunction = file.getFormatNameFunction();
            String fileName = filePath + File.separator + formatNameFunction.apply(tableInfo);
            File targetFile = new File(fileName);

            if (file instanceof EnhanceCustomFile enhanceCustomFile) {
                Map<String, Object> extParams = new HashMap<>();
                dataMap.put(enhanceCustomFile.getFileName(), extParams);
                dataMap.put("currentScope", extParams);
                extParams.put("packageName", file.getPackageName());
                String mainName = FileNameUtil.mainName(targetFile.getName());
                //去掉后缀后的文件名，如果是Java类，等同于类名
                extParams.put("simpleName", mainName);
                extParams.put("fullClassName", file.getPackageName() + "." + FileNameUtil.mainName(fileName));
                extParams.put("path", filePath);
                extParams.put("targetFile", targetFile);
                Class<?> superClass = enhanceCustomFile.getSuperClass();
                if (superClass != null) {
                    extParams.put("importSuperPackage", superClass.getPackageName() + "." + superClass.getSimpleName());
                    extParams.put("superClassSimpleName", superClass.getSimpleName());
                }
                Map<?, ?> packageMap = (Map<?, ?>) dataMap.get("package");
                //"Entity" "Mapper"  "customFile1"  "Xml"  "ServiceImpl"  "Service"  "Controller"，以及自定义文件的namespace
                Map<String, Map<String, Object>> allFileMap = packageMap.entrySet().stream().map(entry -> {
                            String key = (String) entry.getKey();
                            if ("ModuleName".equals(key) || "Parent".equals(key)) {
                                return null;
                            }
                            Map<String, Object> tmpMap = new HashMap<>();
                            String packageStr = (String) entry.getValue();
                            tmpMap.put("package", packageStr);
                            String fieldName = StrUtil.lowerFirst(key) + "Name";
                            boolean b = FieldUtil.hasField(tableInfo.getClass(), fieldName);
                            if (b) {
                                //是mp本身的文件属性
                                tmpMap.put("simpleName", FieldUtil.getFieldValue(tableInfo, fieldName));
                                List<String> list = Arrays.stream(OutputFile.values()).map(Enum::name).toList();
                                OutputFile outputFile;
                                if (list.contains(StrUtil.lowerFirst(key))) {
                                    outputFile = OutputFile.valueOf(StrUtil.lowerFirst(key));
                                    tmpMap.put("path", tableInfo.getPackageConfig().getPathInfo().get(outputFile));
                                }
                            } else {
                                //自定义文件
                                Map<?, ?> extMap = (Map<?, ?>) dataMap.get(key);
                                if (extMap != null) {
                                    tmpMap.put("simpleName", extMap.get("simpleName"));
                                    tmpMap.put("path", extMap.get("path"));
                                } else {
                                    //后一个自定义文件可以拿到前一个自定义文件的附加属性
                                    return null;
                                }
                            }
                            return new DefaultMapEntry<>(key, tmpMap);
                        })
                        .filter(Objects::nonNull)
                        .collect((Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)));
                extParams.put("files", allFileMap);
                List<String> packageList = new ArrayList<>();
                extParams.put("package", packageList);
                extParams.put("superClass", enhanceCustomFile.getSuperClass());
                BiConsumer<Map<String, Object>, TableInfo> extParamsFunction = enhanceCustomFile.getExtParamsFunction();
                if (extParamsFunction != null) {
                    extParamsFunction.accept(extParams, tableInfo);
                }
            }
            outputFile(targetFile, dataMap, file.getTemplatePath(), file.isFileOverride());
        }
    }

}